/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1997-1999 by Sun Microsystems, Inc.
 * All rights reserved.
 */

/*
 * db.c -- the tiny database for trace.  Only stores
 *	global things: see symtab for per-function data.
 *
 */

#include <stdio.h>
#include <string.h>
#include <libgen.h>
#include <limits.h>
#include <sys/param.h>
#include "parser.h"
#include "trace.h"
#include "util.h"
#include "errlog.h"
#include "db.h"

static int curr_print_type;

static struct {
	char	Current_Library[PATH_MAX];
	char	Current_File[PATH_MAX];
	char	Output_File[PATH_MAX];
	char	Current_Interface[PATH_MAX];
	char	Source_Directory[PATH_MAX];
	char	Target_Directory[PATH_MAX];
	int	NFiles;
	int	Verbosity;
	char	Library_List[PATH_MAX];
	char	Translator[MAXNAMELEN];
	char	Test_Type[MAXNAMELEN];
	char	Kludge[PATH_MAX];
	int	Flags;
	char const *Arch;
	table_t	*Print_Types;
	table_t	*File;
	table_t	*Exclusions;

} Database;


/* Generated by m4 -- character string values */
void
db_set_current_library(char const *p)
{
	errlog(BEGIN, "db_set_current_library() {");
	(void) strncpy(Database.Current_Library, p,
	    sizeof (Database.Current_Library));
	Database.Current_Library[sizeof (Database.Current_Library) - 1] = '\0';
	errlog(END, "}");
}

char *
db_get_current_library(void)
{
	errlog(BEGIN, "db_get_current_library() {"); errlog(END, "}");
	return (Database.Current_Library);
}

void
db_set_current_interface(char const *p)
{
	errlog(BEGIN, "db_set_current_interface() {");
	(void) strncpy(Database.Current_Interface, p,
	    sizeof (Database.Current_Interface));
	Database.Current_Interface[
		sizeof (Database.Current_Interface) - 1] = '\0';
	errlog(END, "}");
}

char *
db_get_current_interface(void)
{
	errlog(BEGIN, "db_get_current_interface() {"); errlog(END, "}");
	return (Database.Current_Interface);
}


void
db_set_source_directory(char const *p)
{
	errlog(BEGIN, "db_set_source_directory() {");
	(void) strncpy(Database.Source_Directory, p,
	    sizeof (Database.Source_Directory));
	Database.Source_Directory[sizeof (Database.Source_Directory) - 1] =
	    '\0';
	errlog(END, "}");
}

char *
db_get_source_directory(void)
{
	errlog(BEGIN, "db_get_source_directory() {"); errlog(END, "}");
	return (Database.Source_Directory);
}


void
db_set_target_directory(char const *p)
{
	errlog(BEGIN, "db_set_target_directory() {");
	(void) strncpy(Database.Target_Directory, p,
	    sizeof (Database.Target_Directory));
	Database.Target_Directory[sizeof (Database.Target_Directory) - 1] =
	    '\0';
	errlog(END, "}");
}

char *
db_get_target_directory(void)
{
	errlog(BEGIN, "db_get_target_directory() {"); errlog(END, "}");
	return (Database.Target_Directory);
}

void
db_set_current_file(char const *p)
{
	(void) strncpy(Database.Current_File, p,
		sizeof (Database.Current_File));
	Database.Current_File[sizeof (Database.Current_File) - 1] = '\0';
}

char *
db_get_current_file(void)
{
	return (Database.Current_File);
}


/*
 * Output File -- set from either -o option or file name.
 */
void
db_set_output_file(char const *p)
{
	char	*q;

	errlog(BEGIN, "db_set_output_file() {");
	if (p == NULL) {
		errlog(END, "}");
		return;
	}

	(void) strncpy(Database.Output_File, p, sizeof (Database.Output_File));
	if ((q = strrchr(Database.Output_File, '.')) != NULL) {
		*q = '\0';
	} else {
		Database.Output_File[sizeof (Database.Output_File) - 1] = '\0';
	}
	errlog(VERBOSE, "output file = '%s'\n", Database.Output_File);
	errlog(END, "}");
}

char *
db_get_output_file(void)
{
	static char buffer[MAXLINE];
	char	*p, *q;

	errlog(BEGIN, "db_get_output_file() {");
	if (*Database.Output_File != '\0') {
		/* It was set with the -o option */
		errlog(VERBOSE, "output file from -o = '%s'\n",
			Database.Output_File);
		errlog(END, "}");
		return (Database.Output_File);
	} else {
		/* We generate it from the current input file. */
		(void) strncpy(buffer, Database.Current_File, sizeof (buffer));
		p = basename(buffer);
		if ((q = strrchr(p, '.')) != NULL) {
			*q = '\0';
		}
		errlog(VERBOSE, "output file from input = '%s'\n", p);
		errlog(END, "}");
		return (p);
	}
}

/*
 * Manually written table code.
 */

/*
 * add_print_types -- add legal print types.  Check for void
 *	moved here out of collect, as collect isn't good enough
 *	quality of parser to have a single code path for
 *	types. (Shudder)  Subsequently changed to use special-purpose
 *	test for membership.  Also shudder!
 */

void
db_add_print_types(char *print_type, char *c_type)
{
	char    buffer[MAXLINE];

	errlog(BEGIN, "db_add_print_types() {");

	(void) snprintf(buffer, sizeof (buffer), "%s, %s", print_type, c_type);
	if (Database.Print_Types == NULL) {
		Database.Print_Types = create_string_table(50);
	}
	if (in_string_table(Database.Print_Types, print_type) == NO) {
		Database.Print_Types = add_string_table(Database.Print_Types,
		    &buffer[0]);
	}

	errlog(END, "}");
}

char *
db_get_first_print_type(void)
{
	curr_print_type = 1;
	return (get_string_table(Database.Print_Types, 0));
}

char *
db_get_next_print_type(void)
{

	return (get_string_table(Database.Print_Types, curr_print_type++));
}


void
db_sort_print_types(void)
{
	errlog(BEGIN, "db_sort_print_types() {");
	sort_string_table(Database.Print_Types);
	errlog(END, "}");
}

void
db_set_arch(char const *arch)
{
	Database.Arch = arch;
}

char const *
db_get_arch(void)
{
	return (Database.Arch);
}
